package com.example.springtrans.controller;

import com.example.springtrans.service.UserService;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

@RequestMapping("/trans")
@RestController
public class TransController {
    @Autowired
    private UserService userService;

    /**
     * 自动开启事务，自动提交/回滚事务
     * @param userName
     * @param password
     * @return
     */
    @Transactional
    @RequestMapping("/register")
    public boolean register(String userName,String password){
        if(!StringUtils.hasLength(userName)||!StringUtils.hasLength(password)){
            return false;
        }
        //如果异常捕获了，就会提交，没有捕获，就回滚
        try {
            int a = 10 / 0;
        } catch (Exception e) {
            e.getMessage();
        }
        userService.insert(userName,password);
        return true;
    }

    @Transactional
    @RequestMapping("/register2")
    public boolean register2(String userName,String password){
        if(!StringUtils.hasLength(userName)||!StringUtils.hasLength(password)){
            return false;
        }
        //再把异常抛出就回滚
        try {
            int a = 10 / 0;
        } catch (Exception e) {
            throw e;
        }
        userService.insert(userName,password);
        return true;
    }
    @Transactional
    @RequestMapping("/register3")
    public boolean register3(String userName,String password){
        if(!StringUtils.hasLength(userName)||!StringUtils.hasLength(password)){
            return false;
        }

        try {
            int a = 10 / 0;
        } catch (Exception e) {
            //手动回滚
            //TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();;
        }
        userService.insert(userName,password);
        return true;
    }

    /**
     * 事务提交了
     * @param userName
     * @param password
     * @return
     * @throws IOException
     */
    @Transactional
    @RequestMapping("/register4")
    public boolean register4(String userName,String password) throws IOException {
        if(!StringUtils.hasLength(userName)||!StringUtils.hasLength(password)){
            return false;
        }
        userService.insert(userName,password);
        if(true){
            throw new IOException();
        }
        return true;
    }

    /**
     * 事务回滚
     * @param userName
     * @param password
     * @return
     */
    @SneakyThrows
    @Transactional
    @RequestMapping("/register5")
    public boolean register5(String userName,String password) {
        if(!StringUtils.hasLength(userName)||!StringUtils.hasLength(password)){
            return false;
        }
        userService.insert(userName,password);
        if(true){
            throw new IOException();
        }
        return true;
    }

    /**
     * 事务又回滚了
     * @param userName
     * @param password
     * @return
     */
    @Transactional
    @RequestMapping("/register6")
    public boolean register6(String userName,String password)  {
        if(!StringUtils.hasLength(userName)||!StringUtils.hasLength(password)){
            return false;
        }
        userService.insert(userName,password);
        if(true){
            throw new RuntimeException();
        }
        return true;
    }

    /**
     * 事务回滚
     * @param userName
     * @param password
     * @return
     * @throws IOException
     */
    @Transactional(rollbackFor = Exception.class,isolation = Isolation.DEFAULT)
    @RequestMapping("/register7")
    public boolean register7(String userName,String password) throws IOException {
        if(!StringUtils.hasLength(userName)||!StringUtils.hasLength(password)){
            return false;
        }
        userService.insert(userName,password);
        if(true){
            throw new IOException();
        }
        return true;
    }
}
